<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Amap;
use app\common\UsersService;
use app\model\HkArea;
use app\model\Recruit;
use app\model\RecruitClass;
use app\model\RecruitComment;
use app\model\UsersRelated;
use app\model\UsersShield;
use app\Request;
use app\tool\GpsUtils;
use app\tool\Http;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\response\Json;

class RecruitController extends BaseController
{
	
	protected array $middleware = [
		'Login' => ['except' => ['test','index', 'read', 'get_json', 'comment_list', 'class']],
		'Location' => ['only' => ['index', 'read']],
	];
	
	/**
	 * 屏蔽
	 * @param Request $request
	 * @return void
	 */
	function shield(Request $request)
	{
		$id = $request->post('id/d');
		UsersShield::create([
			'users_id'=>$request->users_id,
			'pro_id'=>$id,
			'type'=>'recruit'
		]);
		writeJson();
	}
	
	/**
	 * 求职招聘-列表
	 * @return Json
	 */
	public function index(Request $request,int $type, int $class_id, mixed $hk_area_id, int $default, string $keyword): Json
	{
		$shield = UsersShield::where(['users_id'=>$request->users_id,'type'=>'recruit'])->column('pro_id');
		
		$lat = self::$latitude;
		$lng = self::$longitude;
		$rows = Recruit::with(['users'])
			->field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
			->where('type', $type)
			->filter(function ($data) use ($lat, $lng) {
				if (empty($lat) || empty($lng)) {
					$data->distance_text = '';
				} else {
					if (empty($data->latitude)||empty($data->longitude)){
						$data->distance_text = '';
					}else{
						if ($data->distance == 0) {
							$data->distance_text = '0m';
						} elseif (0 < $data->distance && $data->distance < 1) {
							$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
						} else {
							$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
						}
					}
				}
			})
			->whereNotIn('id',$shield)
			->when(!empty($class_id), function (Query $query) use ($class_id) {
				$query->where(['class_id' => $class_id]);
			})
			->when(!empty($hk_area_id) && $hk_area_id != 3, function (Query $query) use ($hk_area_id) {
				$query->whereFindInSet('hk_area_ids', $hk_area_id);
			})
			->when(!empty($default), function (Query $query) use ($default, $lng, $lat) {
				switch ($default) {
					case 1:
						$query->order(['source'=>'asc','id'=>'desc']);
						break;
					case 2:
						$query->order('browse', 'desc');
						break;
					case 3:
						$query->order('createtime', 'desc');
						break;
					case 4:
						$query->where('images', '<>', null);
						break;
					case 5:
						if (empty($lat) || empty($lng)) {
							$query->order('createtime', 'desc');
						} else {
							$query->order('distance', 'asc');
						}
						break;
				}
			})
			->when(!empty($keyword), function (Query $query) use ($keyword) {
				$query->whereLike('title|content', '%' . $keyword . '%');
			})
			->paginate()
			->items();
		
		writeJson($rows);
	}
	
	/**
	 * 分类
	 * @return void
	 */
	function class()
	{
		$rows = RecruitClass::order(['weigh' => 'desc'])->select()->toArray();
		array_unshift($rows, ['id' => 0, 'name' => '不限']);
		writeJson($rows);
	}
	
	/**
	 * 求职招聘-发布
	 * @param Request $request
	 * @return Json
	 */
	public function save(Request $request): Json
	{
		$params = $request->param();
		if (!empty($params['longitude']) && !empty($params['latitude'])) {
			$ids = HkArea::where([['top', '>=', $params['latitude']], ['bottom', '<=', $params['latitude']], ['left', '<=', $params['longitude']], ['right', '>=', $params['longitude']]])->column('id');
			$ids = implode(',', $ids);
			$params['hk_area_ids'] = $ids;
		}
        $params['source'] = 1;
 		$res = Recruit::create($params);
		$res->distance_text = '0m';
		writeJson($res->append(['users']));
	}
	
	/**
	 * 点赞
	 * @param Request $request
	 * @return Json
	 */
	function like(Request $request)
	{
		$id = $request->post('id');
		$res = UsersService::like($id, $request->users_id, 'recruit');
		$res ? event('RecruitIncLike', $id) : event('RecruitDecLike', $id); //增加/减少  点赞数量
		if ($res) {
			$pro = Recruit::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 3, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	/**
	 * 收藏
	 * @param Request $request
	 * @return Json
	 */
	function collect(Request $request)
	{
		$id = $request->post('id');
		$res = UsersService::collect($id, $request->users_id, 'recruit');
		$res ? event('RecruitIncCollect', $id) : event('RecruitDecCollect', $id); //增加/减少  收藏数量
		if ($res) {
			$pro = Recruit::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 7, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	/**
	 * 详情
	 * @param int $id
	 * @return Json
	 */
	public function read(int $id, Request $request)
	{
		$lat = self::$latitude;
		$lng = self::$longitude;
		$row = Recruit::with([
			'users',
			'users_collect' => function (Query $query) use ($request) {
				$query->where(['users_id' => $request->users_id, 'type' => 'recruit']);
			},
			'users_like' => function (Query $query) use ($request) {
				$query->where(['users_id' => $request->users_id, 'type' => 'recruit']);
			}])
			->field("*,(6371 * acos (cos ( radians($lat) ) * cos( radians( latitude ) ) * cos( radians(longitude) - radians( $lng ) ) + sin ( radians( $lat ) ) * sin( radians( latitude ) ))) AS distance")
			->filter(function ($data) use ($lat, $lng) {
				if (empty($lat) || empty($lng)) {
					$data->distance_text = '';
				} else {
					if ($data->distance == 0) {
						$data->distance_text = '0m';
					} elseif (0 < $data->distance && $data->distance < 1) {
						$data->distance_text = bcmul((string)$data->distance, '1000') . 'm';
					} else {
						$data->distance_text = bcmul((string)$data->distance, '1', 1) . 'km';
					}
				}
				
			})
			->find($id);
		UsersService::footmark($id, $request->users_id, 'recruit');
		event('RecruitIncBrowse', $id); //增加浏览数量
		writeJson($row);
	}
	
	
	/**
	 * 评论列表
	 * @param int $recruit_id
	 * @param mixed $comment_id
	 * @param Request $request
	 * @return Json
	 */
	function comment_list(int $recruit_id, mixed $comment_id, Request $request)
	{
		
		$top_id = 0;
		if (!empty($comment_id)) {
			$row = RecruitComment::find($comment_id);
			if ($row->pid == 0) {
				//顶级评论 放在第一条
				$top_id = $row->id;
			} else {
				//子评论 找出顶级评论
				$row = RecruitComment::find($row->pid);
				$top_id = $row->id;
			}
		}
		
		$rows = RecruitComment::where(['pid' => 0, 'recruit_id' => $recruit_id])->withCount('comment')->with([
			'users',
			'users_like' => function (Query $query) use ($request) {
				$query->where(['users_id' => $request->users_id, 'type' => 'recruit_comment']);
			},
			'comment' => function (Query $query) use ($request, $comment_id) {
				$query
					->with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
						$query->where(['users_id' => $request->users_id, 'type' => 'recruit_comment']);
					}])
					->when(!empty($comment_id), function (Query $query) use ($comment_id) {
						$query->field("*,IF(id = $comment_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
					}, function (Query $query) {
						$query->order(['id' => 'desc']);
					})
					->limit($this->comment_list_rows);
			}])
			->when(!empty($comment_id), function (Query $query) use ($top_id) {
				$query->field("IF(id = $top_id,1,0) AS top")->order(['top' => 'desc', 'id' => 'desc']);
			}, function (Query $query) {
				$query->order(['id' => 'desc']);
			})
			->paginate()
			->items();
		
		writeJson($rows);
	}
	
	/**
	 * 评论详情
	 * @param int $id
	 * @param mixed $comment_id
	 * @param Request $request
	 * @return Json
	 */
	function comment_detail(int $id, mixed $comment_id, Request $request)
	{
		$child = false;
		if (!empty($comment_id)) {
			$row = RecruitComment::find($comment_id);
			if ($row->pid != 0) {
				//二级评论
				$child = true;
			}
		}
		$rows = RecruitComment::where(['pid' => $id])
			->with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
				$query->where(['users_id' => $request->users_id, 'type' => 'recruit_comment']);
			}])
			->when($child, function (Query $query) use ($comment_id) {
				$query->where('id', '<>', $comment_id);
			})
			->order(['id' => 'desc'])
			->paginate($this->comment_detail_rows)
			->items();
		writeJson($rows);
	}
	
	/**
	 * 评论点赞
	 * @param Request $request
	 * @return Json
	 */
	function comment_like(Request $request)
	{
		$id = $request->param('id');
		$res = UsersService::like($id, $request->users_id, 'recruit_comment');
		$res ? event('RecruitCommentIncLike', $id) : event('RecruitCommentDecLike', $id); //增加/减少  点赞数量
		if ($res) {
			$pro = RecruitComment::find($id);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 4, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $id]);
		}
		writeJson($res);
	}
	
	/**
	 * 评论
	 * @param Request $request
	 * @return Json
	 */
	function comment(Request $request): Json
	{
		$params = $request->param();//recruit_id   to_users_id  pid  content
		$ip = $request->ip();
		$params['ip'] = $ip;
		$ip = Amap::ip($ip);
		$ip = json_decode($ip);
		if ($ip->status == 1) {
			$params['city'] = $ip->province;
		} else {
			$params['city'] = '未知';
		}
		$res = RecruitComment::create($params);
		foreach ($params['content'] as $v) {
			if ($v['type'] == 'at') {
				//@提醒  提醒接收人
				UsersRelated::create(['users_id' => $v['userId'], 'type' => 8, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $res->id]);
			}
		}
		if (!empty($params['to_users_id'])) {
			//回复提醒  提醒接收人
			UsersRelated::create(['users_id' => $params['to_users_id'], 'type' => 1, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $res->id]);
		} else {
			//评论提醒  提醒发布人
			$pro = Recruit::find($params['recruit_id']);
			UsersRelated::create(['users_id' => $pro->users_id, 'type' => 2, 'from_users_id' => $request->users_id, 'scene' => 'Recruit', 'pro_id' => $res->id]);
		}
		event('RecruitIncComment', $params['recruit_id']); //增加评论数量
		$row = RecruitComment::with(['users', 'to_users', 'users_like' => function (Query $query) use ($request) {
			$query->where(['users_id' => $request->users_id, 'type' => 'recruit_comment']);
		}])->find($res->id);
		writeJson($row);
	}
	
	/**
	 * 批量删除
	 * @param Request $request
	 * @return Json
	 * @throws DataNotFoundException
	 * @throws DbException
	 * @throws ModelNotFoundException
	 */
	function delete(Request $request)
	{
		$ids = $request->post('ids');
		Recruit::where(['users_id' => $request->users_id])->whereIn('id', $ids)->select()->delete();
		writeJson();
	}
	
	function get_json()
	{
		ignore_user_abort(true); // 关闭浏览器 继续执行
		set_time_limit(0); // 执行时间为无限制
		ini_set("memory_limit","-1");
		
		$company = Http::get('https://opendata.hkstp.org/corporate/companydirectory/v1', [], [CURLOPT_ENCODING => 'GZIP']);
		$company = json_decode($company);
		
		$company = $company->value;
		$company_name = array_column($company, 'name_EN');
		$res = Http::get('https://opendata.hkstp.org/corporate/recruitment/v1', [], [CURLOPT_ENCODING => 'GZIP']);
		$res = json_decode($res);
		
		foreach ($res as $k) {
			$row = Recruit::where(['unique' => $k->Job_Position])->find();
			if (!$row) {
				$index = array_search($k->Company_Name, $company_name);
				$company_detail = $company[$index];
				Recruit::create([
					'users_id' => 3,
					'type' => 0,
					'salary' => $k->Salary ? ($k->Salary == 'Negotiable' ? '面议' : $k->Salary) : '面议',
					'recruit' => 0,
					'title' => $k->Job_Position,
					'content' =>
						'<p>职位名称：' . $k->Job_Position . '</p>' .
						'<p>工作性质：' . $k->Job_Industry . '</p>' .
						'<p>薪水：' . $k->Salary . '</p>' .
						'<p>工作经验：' . $k->Work_Experience . '</p>' .
						($k->Education_Level ? '<p>学历要求：' . $k->Education_Level . '</p>' : '') .
						'<p>职业水平：' . $k->Career_Level . '</p>' .
						'<p>就业类型：' . $k->Employment_Type . '</p>' .
						'<p>聘期：' . $k->Employment_Term . '</p>' .
						'<p>截止申请日期：' . $k->Post_End_Date . '</p>' .
						'<p>公司名称：' . $k->Company_Name . '</p>' .
						'<p>工作地点：' . $k->Work_Location . '</p>' .
						($company_detail->introduction_SC ? '<p>公司介绍：' . $company_detail->introduction_SC . '</p>' : '') .
						($company_detail->product_SC ? '<p>产品介绍：' . $company_detail->product_SC . '</p>' : '') .
						($company_detail->website ? '<p>公司网址：' . $company_detail->website . '</p>' : '') .
						($company_detail->email ? '<p>电子邮箱：' . $company_detail->email . '</p>' : '') .
						($company_detail->contact_TC ? '<p>联系人：' . $company_detail->contact_TC . '</p>' : ''),
					'unique' => $k->Job_Position
				]);
			}
		}
		$res = Http::get('https://www.csb.gov.hk/datagovhk/gov-vacancies/gov-job-vacancies-sc.json');
		$res = json_decode(trim($res, chr(239) . chr(187) . chr(191)));
		$res = $res->common;
		$res = $res[0]->vacancies;
		foreach ($res as $k) {
			$row = Recruit::where(['unique' => $k->jobid])->find();
			if (!$row) {
				$academic = array_unique($k->academic);
				$academic = implode(',', $academic);
				$data = [
					'users_id' => 3,
					'type' => 0,
					'salary' => ($k->minpaym ? '月薪：' . $k->minpaym . $k->ccym : '面议') . ($k->minpayd ? '日薪：' . $k->minpayd . $k->ccyd : '') . ($k->minpayd ? '时薪：' . $k->minpayh . $k->ccyh : ''),
					'recruit' => 0,
					'title' => $k->jobname,
					'content' =>
						'<p>职位名称：' . $k->jobname . '</p>' .
						'<p>工作性质：' . $k->jobnature . '</p>' .
						'<p>' . ($k->minpaym ? '月薪：' . $k->minpaym . $k->ccym : '') . ($k->minpayd ? '日薪：' . $k->minpayd . $k->ccyd : '') . ($k->minpayd ? '时薪：' . $k->minpayh . $k->ccyh : '') . '</p>' .
						'<p>工作经验：' . ($k->expfrom == 0 ? '无需工作经验' : $k->expfrom . '年工作经验') . '</p>' .
						'<p>学历要求：' . $academic . '</p>' .
						'<p>职责：' . $k->duties . '</p>' .
						'<p>入职条件：' . $k->entreq . '</p>' .
						'<p>补充资料：' . $k->ernotes . '</p>' .
						'<p>聘用条款：' . $k->appterm . '</p>' .
						'<p>备注：' . $k->appnotes . '</p>' .
						'<p>申请手续：' . $k->appmethod . '</p>' .
						'<p>截止申请日期：' . $k->enddate . '</p>' .
						'<p>部门网址：' . $k->depturl . '</p>' .
						'<p>部门在线申请网址：' . $k->onlineformurl . '</p>' .
						'<p>递交申请链接：' . $k->submitdocumentlink . '</p>' .
						'<p>工作地点：' . $k->enqaddr . '</p>' .
						'<p>联系方式：' . $k->enqtel . '</p>' .
						'<p>提交申请的邮箱：' . $k->applyemail . '</p>',
					'unique' => $k->jobid,
				
				];
				if (!empty($k->enqtel)) {
					$point = Http::get("https://geodata.gov.hk/gs/api/v1.0.0/locationSearch", ['q' => $k->enqtel]);
					$point = json_decode($point);
					if (!empty($point)) {
						$point = $point[0];
						list($lng, $lat) = GpsUtils::hk80ToWgs84($point->x, $point->y);
						$data['longitude'] = $lng;
						$data['latitude'] = $lat;
						$data['address']=$k->enqaddr;
						$ids = HkArea::where([['top', '>=', $lat], ['bottom', '<=', $lat], ['left', '<=', $lng], ['right', '>=', $lng]])->column('id');
						$ids = implode(',', $ids);
						$data['hk_area_ids'] = $ids;
					}
				}
				Recruit::create($data);
			}
		}
		$res = Http::get('https://www.ogcio.gov.hk/sc/about_us/vacancies/index.data.json');
		$res = json_decode($res);
		$res = $res->{'job-vacancies'};
		$row = Recruit::where(['unique' => $res[0]->topic])->find();
		if (!$row) {
			Recruit::create([
				'users_id' => 3,
				'type' => 0,
				'salary' => '面议',
				'recruit' => 0,
				'title' => $res[0]->topic,
				'content' => $res[2]->date,
				'unique' => $res[0]->topic
			]);
		}
	
		writeJson();
		
	}
	
}
